package main

import (
	"fmt"
	"net"
)

func main() {
	const IcmpLen = 8
	var msg [512]byte
	msg[0] = 8 // type
	msg[1] = 0 // code
	msg[2] = 0 // checkSum -> 2 byte
	msg[3] = 0
	msg[4] = 1  // identifier[0]
	msg[5] = 13 // identifier[1]
	msg[6] = 0  // sequence[0]
	msg[7] = 37 // sequence[1]
	// 检验和
	check := checkSum(msg[:IcmpLen])
	msg[2] = byte(check >> 8)
	msg[3] = byte(check & 255)

	remoteAddr, err := net.ResolveIPAddr("ip", "192.168.55.181")
	if err != nil {
		fmt.Println("error: ", err)
		return
	}
	// 拨号
	conn, err := net.DialIP("ip:icmp", nil, remoteAddr)
	if err != nil {
		fmt.Println("error: ", err)
		return
	}
	// 发送数据
	if _, err := conn.Write(msg[:IcmpLen]); err != nil {
		fmt.Println("send data error: ", err)
		return
	}
	// 读取返回的数据
	fmt.Println(msg[:IcmpLen])
	var receive [512]byte
	size, err := conn.Read(receive[:])
	if err != nil {
		fmt.Println("error: ", err)
		return
	}
	fmt.Println(receive[:size])

	for i := 0; i < len(receive[:size]); i++ {
		fmt.Printf("%b\n", receive[i])
	}
}

func checkSum(msg []byte) uint16 {
	sum := 0
	for n := 0; n < len(msg); n += 2 {
		sum += int(msg[n])<<8 + int(msg[n+1])
	}
	sum = (sum >> 16) + sum&0xffff
	sum += sum >> 16
	return uint16(^sum)
}

// [8 0 246 205 1 13 0 37]
// [69 0 0 28 87 24 0 0 64 1 0 0 192 168 55 181 192 168 55 181 0 0 254 205 1 13 0 37]
// 1000101
// 0
// 0
// 11100
// 1010111
// 11000
// 0
// 0
// 1000000
// 1
// 0
// 0
// 11000000
// 10101000
// 110111
// 10110101
// 11000000
// 10101000
// 110111
// 10110101
// 0
// 0
// 11111110
// 11001101
// 1
// 1101
// 0
// 100101
